package com.unionpay.atm.sdk;

import java.nio.charset.Charset;

/**
 * Implementation of class UserIdentityComparison to compare the user identity information.
 */
public class UserIdentityComparison {
	
	private static final int DIGEST_LENGTH = 32;            // sm3 digest length(32 bytes)
	private static final int NAME_LENGTH = 30;              // user name length(30 bytes)
	private static final int CERTTYPE_LENGTH = 2;           // user certificate type(2 bytes)
	private static final int CERTNO_LENGTH = 20;            // user certificate number(20 bytes)
	private String sName ;
	private String sCertType;
	private String sCertNo;
	private SM3Digest digest;
	
	/**
     * constructor
     * @param sName: user name
     * @param sCertType: user certificate type
     * @param sCertNo: user certificate number
     */
	UserIdentityComparison(String sName, String sCertType, String sCertNo)
	{
		this.sName = sName;
		this.sCertType = sCertType;
		this.sCertNo = sCertNo;
		this.digest = new SM3Digest();
	}
	
	/**
     * get user messages'(sNames,CertType and sCertNo)sm3 digest according to rules
     * @return byte array result according to the rules(i.e., convert to capital letters,strip the blank space, 
     * and pad black space in the end)
     * @exception IndexOutOfBoundsException
     */
	public byte[] getUserInfoBytes()
	{
		if(0 == this.sName.length() || 0 == this.sCertType.length() || 0 == this.sCertNo.length())
    	{
    		System.out.println("sName or sCertType or sCertNo is null");
    		return new byte[0];
    	}	
		
    	// firstly, convert parameters to capital letters. 
		// secondly, strip the left blank space in beginning.
		// In the end, if parameters are less than the given length, fill with black space. 
		byte[] bName = fillWithByte(leftTrimBlank(this.sName.toUpperCase()), NAME_LENGTH, (byte)' '); 
		byte[] bCertType = fillWithByte(leftTrimBlank(this.sCertType.toUpperCase()), CERTTYPE_LENGTH, (byte)' '); 
		byte[] bCertNo = fillWithByte(leftTrimBlank(this.sCertNo.toUpperCase()), CERTNO_LENGTH, (byte)' '); 

    	// get concatenation byte array 
    	byte[] bArrOut = new byte[bName.length + bCertType.length + bCertNo.length];
    	System.out.println("bArrOut.len:"+bArrOut.length);
    	try{
    		System.arraycopy(bName, 0, bArrOut, 0, bName.length);
    		System.arraycopy(bCertType, 0, bArrOut, bName.length, bCertType.length);
    		System.arraycopy(bCertNo, 0, bArrOut, bName.length + bCertType.length, bCertNo.length);
    	}catch(IndexOutOfBoundsException ex){
    		ex.printStackTrace();
    	}

    	return bArrOut; 	
	}
	
	/**
     * calculate the messages'(sNames,CertType and sCertNo)sm3 digest according to rules
     * @param bArrInput: the information to generate sm3 digest
     * @return sm3 digest byte array
     */
    public byte[] calSM3Digest(byte[]bArrInput)
    {
    	if(0 == bArrInput.length)
    	{
    		System.out.println("input data is null");
    		return new byte[0];
    	}	
    	
    	return this.digest.calSM3Digest(bArrInput);  // generate sm3 digest
    }
    
    /**
     * trim left black space of the input string 
     * @param sInputStr: input string 
     * @return string after trimming the left black space
     */
    public static String leftTrimBlank(String sInputStr)
    {
    	int iLen = sInputStr.length();
    	if(0 == iLen)
    		return "";
    	int iIndex = 0;
    	 for (int i = 0; i < iLen; i++) {
    		 if(sInputStr.charAt(i) == ' ')
    			 iIndex++;
    		 else
    			 break;
 
         }
         return sInputStr.substring(iIndex);
    }
    
    /**
     * fill with the end of string input with byte variable bPadding 
     * @param sInputStr: string to fill with
     * @param iLength: the byte total length 
     * @param bPadding: the byte to fill with 
     * @return byte array with filled with paddings
     */
    public static byte[] fillWithByte(String sInputStr, int iLength, byte bPadding) {
    	if(0 == sInputStr.length())
    		return new byte[0];
    	byte[] bArrInput = sInputStr.getBytes();
    	byte[] bArrRes = new byte[iLength];
    	if(bArrInput.length >= iLength)
    	{
    		System.arraycopy(bArrInput, 0, bArrRes, 0, iLength);
    		return bArrRes;
    	}
    	
    	System.arraycopy(bArrInput, 0, bArrRes, 0, bArrInput.length);   
        for (int i = bArrInput.length; i < iLength; i++) {
        	bArrRes[i] = bPadding;
        }

        return bArrRes;
    }
    
	
} // end of class UserIdentityComparison




